﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;


// 节拍类型枚举，0-非节拍；1-玩家；2-敌人；3-关卡；
// 数字越大优先级越高
public enum TempoType
{
    // 无节拍
    None = 0,
    // 平A
    NormalAttack = 1,
    // 敌人攻击
    EnemyAttack = 2
}

// 节拍状态枚举
public enum TempoStatus
{
    // 无节拍
    None = -1,
    // 尚未过线
    Intact = 0,
    // 错过
    Miss = 0,
    // 弱
    Good = 1,
    // 强
    Great = 2,
    // 会心
    Perfect = 3
}

// 节拍类
public class Tempo
{
    // 节拍类型
    public TempoType type_of_tempo = TempoType.None;
    // 节拍状态
    public TempoStatus status_of_tempo = TempoStatus.None;
    /*
    //构造函数
    public Tempo()
    {
        this.type_of_tempo = TempoType.None;
        this.status_of_tempo = TempoStatus.None;
    }*/
    // 节拍类（节拍类型，节拍状态）
    public void TempoModify(TempoType t, TempoStatus s)
    {
        type_of_tempo = t;
        status_of_tempo = s;
    }
    // 重写ToString方式
    public override string ToString()
    {
        return "[Tempo]Type: " + type_of_tempo.ToString() + "; Status: " + status_of_tempo.ToString();
    }
}


// 节拍管理器所在对象应在关卡启动后激活
public class TempoManager : MonoBehaviour
{
    // 开启/关闭调试输出
    [SerializeField] private bool isDebug = false;
    // 节拍输入结果的判定范围
    [SerializeField] private float range_Perfect = 0.1f;
    [SerializeField] private float range_Great = 0.2f;
    [SerializeField] private float range_Good = 0.3f;
    // 输入结果对应伤害倍率
    [SerializeField] private float rate_Perfect = 1.5f;
    [SerializeField] private float rate_Great = 1.0f;
    [SerializeField] private float rate_Good = 0.5f;
    [SerializeField] private int Player_ATK = 10;
    // 检测节拍时的最大帧范围
    private int max_check_frame = 40;
    // 记录帧数作为谱面进度基准
    private int frame = -1;
    // 记录当前生成的节拍数
    private int tempo_order = 0;
    // 存放本关谱面的动态数组
    //private ArrayList TempoList = new ArrayList();
    // 节拍类数组长度
    public const int TempoListLength = 2000;
    // 循环存放当前谱面的定长数组
    public Tempo[] TempoArray = new Tempo[TempoListLength];


    private void Awake()
    {
        /*效率监测part1
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        stopwatch.Start();
        */
        //【需要监测的语句】
        /*效率监测part2
        stopwatch.Stop();
        System.TimeSpan timespan = stopwatch.Elapsed;
        double milliseconds = timespan.TotalMilliseconds;   //毫秒
        Debug.Log(milliseconds);
        */
        // 初始化节拍数组
        for(int i = 0;i < TempoListLength;i++)
        {
            TempoArray[i] = new Tempo();
        }
        // 初始化检测节拍时的最大帧范围
        max_check_frame = (int)(range_Good / Time.fixedDeltaTime);
    }

    // Start is called before the first frame update
    // 在第一次enable后、Update之前调用
    void Start()
    {
        frame = -1;  // 帧计数初始化
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void FixedUpdate()
    {
        frame++;    // 帧计数自增
        if (isDebug) Debug.Log("frame : "+frame); // 调试输出
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if(isDebug) Debug.Log("按下空格键"); // 调试输出
            GetClick();
        }
    }

    // 处理单击输入
    public void GetClick()
    {
        //获取最近的节拍点并获取判定结果
        int last_tempo = Query();
        TempoStatus s;
        if (last_tempo >= 0)
        {
            s = Remark(frame, last_tempo);
            ShowHit(s);
            Attack(Player_ATK, s);

        }
    }

    // 添加新节拍(TempoType NormalAttack/EnemyAttack)
    public bool AddNewTempo(int f,TempoType t)
    {
        // 【待修改】
        //TempoList.Add(new Tempo(0,TempoType.NormalAttack));
        if(t > TempoArray[frame % TempoListLength].type_of_tempo)
        {
            TempoArray[frame % TempoListLength].TempoModify(t, TempoStatus.Intact);
        }
        //【待添加】调用UI_HitShow()

        return true;
    }    

    // 查询当前时点的最高优先级节拍点，以frame序号的形式返回
    // 【暂不对比优先级，待加入弹反】
    public int Query()
    {
        /*效率监测part1
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        stopwatch.Start();
        */
        for (int i = 0; i < max_check_frame; i++)
        {
            if (TempoArray[(frame + i) % TempoListLength].status_of_tempo == TempoStatus.Intact)
                return frame + i;
        }
        /*效率监测part2
        stopwatch.Stop();
        System.TimeSpan timespan = stopwatch.Elapsed;
        double milliseconds = timespan.TotalMilliseconds;   //毫秒
        Debug.Log(milliseconds);
        */
        return -1;
    }

    // 判定节拍输入结果
    private TempoStatus Remark(int clickTime, int tempoTime)
    {
        float d = (tempoTime - clickTime) * Time.fixedDeltaTime;
        if (d < 0 || d > range_Good)
        {
            if (d <= range_Perfect)
            {
                return TempoStatus.Perfect;
            }
            else if (d <= range_Great)
            {
                return TempoStatus.Great;
            }
            else if (d <= range_Good)
            {
                return TempoStatus.Good;
            }
            else
            {
                return TempoStatus.None;
            }
        }else
        {
            return TempoStatus.None;
        }
    }

    // 【待完善】伤害发生器，应在角色类后编写
    public bool Attack(float damage, TempoStatus s)
    {
        
        return true;
    }

    // 判定表现
    public void ShowHit(TempoStatus s)
    {
        switch (s)
        {
            case TempoStatus.Good:;//播放Good的UI动画
                break;
            case TempoStatus.Great:;
                break;
            case TempoStatus.Perfect:;
                break;
            default:
                break;
        }
    }

    // 检查帧计数与实际时间流逝是否匹配
    public void CheckTime()
    {
        Debug.Log("Frame Time : "+(float)frame * Time.fixedDeltaTime);
        Debug.Log("Fixed Time : "+Time.fixedTime);
    }

    // 测试节拍队列
    public void CheckTempo(int option)
    {
        switch (option)
        {
            case 0: Debug.Log(TempoArray[1999].ToString()); break;
            case 1: ; break;
            case 2: ; break;
            default: ; break;
        }
    }
}